import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.LinkedList;


/**
 * current design idea for the class that implements this interface:
 * 		1. get the spec file
 * 		2. Regex -> NFA Conversion
 * 			a. createParseTree
 * 			b. createNFA
 * 		3. NFA -> DFA table
 * 		4. Create and return a Parser obj. (Parser can take in a DFA table)
 */

public class DFAParserGenerator implements ParserGenerator
{
	private HashMap<BSTNode<String>, BSTNode<String>> concats;//may change data structure
	private HashMap<BSTNode<String>, BSTNode<String>> recursions;//may change data structure
	private ArrayList<String>fixedSpecName;
	private ArrayList<ArrayList<String>>fixedSpecDef;
	private HashMap<String,CharacterClass> charclasses;
	private BinarySearchTree<String> parseTree;
	//the following are for spec preprocessing (to be used by parseSpecFile) 
	private ArrayList<String> regexNames;
	private ArrayList<String> regexDefs;
	private ArrayList<String> charClassNames;
	private ArrayList<String> charClassDefs;
	
	public static enum CharType {ALPHA_NUMERIC,CHARCLASS_OPERATOR, REGEX_OPERATOR,WHITESPACE,ESCAPE_OPERATOR,NEWLINE,OTHER};
	
	private static CharType getCharType(char c){
		if((64<(byte)c && (byte)c<91)||(96<(byte)c && (byte)c<123)||(47<(byte)c && (byte)c<58)){return CharType.ALPHA_NUMERIC;}
		if(c == 94 || c==91 || c==93 || c==39 || c==34 || c==45 || c==46){return CharType.CHARCLASS_OPERATOR;} // ^,[,],',",-,.
		if(c == 42 || c==43 || c==124 || c==40 || c==41){return CharType.REGEX_OPERATOR;} //+,*,|,(,)
		if(c == 9 || c==32){return CharType.WHITESPACE;} //TAB,SPACE
		if(c== 92)return CharType.ESCAPE_OPERATOR;
		if(c == '\n')return CharType.NEWLINE;
		return CharType.OTHER;
	}
	
	public String charBufferToString(LinkedList<Character> buffer){
		char [] token = new char[buffer.size()];
		for(int i=0;i<buffer.size();i++){token[i]=buffer.get(i);}
		return new String(token);
	}
	
	public class CharacterClass{
		private String name,definition;
		public CharacterClass(String name, String definition){}
		public String getName(){return name;}
		public String getDef(){return name;}
	}
	
	public DFAParserGenerator()
	{
		fixedSpecName = new ArrayList<String>();
		fixedSpecDef = new ArrayList<ArrayList<String>>();
		charclasses = new HashMap<String,CharacterClass>();
		charClassNames = new ArrayList<String>();
		charClassDefs = new ArrayList<String>();
		regexNames = new ArrayList<String>();
		regexDefs = new ArrayList<String>();
	}//end DFAParserGenerator constructor
	public Parser createParser(String specFileName) 
	{
		//Regex preparsing
		try {
			parseSpecFile(specFileName);
			for(int i=0;i<charClassNames.size();i++){
				CharacterClass charclass = new CharacterClass(charClassNames.get(i),charClassDefs.get(i));
				charclasses.put(charclass.getName(), charclass);
			}
			for(int i=0;i<regexNames.size();i++){
				fixedSpecName.add(regexNames.get(i));
			}
			for(int i=0;i<regexDefs.size();i++){
				fixedSpecDef.add(splitRegexDefinition(regexDefs.get(i)));
			}
			removeLeftRecursion(fixedSpecName,fixedSpecDef);
			parseTree = createParseTree();
			NFA<String> nfa = createNFA((BST<String>)parseTree);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}//end createParser method
	
	public ArrayList<String> splitRegexDefinition(String regexdef){
		for
		return null;
	}

	public void parseSpecFile(String filepath) throws IOException{
		BufferedReader input = null;
		LinkedList<Character> keybuffer = new LinkedList<Character>();
		LinkedList<Character> defbuffer = new LinkedList<Character>();
		//regexNames, regexDefs, charClassNames, charClassDefs;
		ArrayList<String> keyList = charClassNames;
		ArrayList<String> defList = charClassDefs;
		keyList.clear(); defList.clear();
		//flow flags
		boolean keyFlag = true;
		boolean buffering=false;
		char lastChar = 0;
		File file = new File(filepath);
	    if (!file.exists()) {
	      System.out.println(filepath + " does not exist.");
	      return;
	    }
	    if (!(file.isFile() && file.canRead())) {
	      System.out.println(file.getName() + " cannot be read from.");
	      return;
	    }
	    try {
	      input = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
	      int current=-1;
	      while (true) {
	    	input.mark(1);
	    	if((current = input.read()) == -1) break;
	    	if(keyFlag){//attempting to add char to keybuffer
	    		if(current == '\n' && !keyList.isEmpty() && lastChar== '\n'){//signals the end of charclass defs
	    			keyList = regexNames; defList = regexDefs;
	    		}
	    		else{
	    			if(buffering){
	    				if(getCharType((char)current)==CharType.WHITESPACE){
	    					keyList.add(charBufferToString(keybuffer));
	    					keybuffer.clear();
	    					buffering = false;
	    					keyFlag = false;
	    				}
	    				else{ keybuffer.add((char)current);}
	    			}
	    			else{
	    				if(getCharType((char)current)==CharType.WHITESPACE){
	    					buffering =true;
	    					keybuffer.add((char)current);
	    				}
	    			}
	    		}
	    	}
	    	else{//attempting to add char to defbuffer
	    		if(buffering){
	    			if(getCharType((char)current)!=CharType.NEWLINE){
	    				defbuffer.add((char)current);
	    			}
	    			else{
	    				defList.add(charBufferToString(defbuffer));
	    				defbuffer.clear();
	    				buffering = false;
	    				keyFlag = true;
	    			}
	    		}
	    		else{
	    			if( getCharType((char)current) != CharType.WHITESPACE){
	    				defbuffer.add((char)current);
	    				buffering = true;
	    			}
	    		}
	    	}
	    	lastChar = (char)current;
	      }
	      //consistency checks for charClass and regex names and definitions
	      if(charClassNames.size()!=charClassDefs.size()){
	    	  System.out.println("Incomplete pairing of CharClass name and definitions.");
	    	  if(charClassNames.size()<charClassDefs.size()){ System.out.println("Missing Identifiers!"); }
	    	  else{ System.out.println("Missing Definitions!"); }
	      }
	      if(regexNames.size()!=regexDefs.size()){
	    	  System.out.println("Incomplete pairing of regex rule names and definitions.");
	    	  if(regexNames.size()<regexDefs.size()){ System.out.println("Missing Identifiers!"); }
	    	  else{ System.out.println("Missing Definitions!"); }
	      }
	      if(charClassNames.isEmpty() && charClassDefs.isEmpty()){ System.out.println("No Character Class Definitions found!"); }
	      if(regexNames.isEmpty() && regexDefs.isEmpty()){ System.out.println("No Regex rules found!"); }
	    } 
	    catch (Exception e) {
	      e.printStackTrace();
	    }
	    finally{
	    	input.close();
	    }
		return;
	}
	
	public void removeLeftRecursion(ArrayList<String> tokNames, ArrayList<ArrayList<String>> tokDefs)
	{
		ArrayList<String> names = new ArrayList<String>();
		ArrayList<ArrayList<String>> defs = new ArrayList<ArrayList<String>>();
		String newName = "";
		ArrayList<String> newDefs = new ArrayList<String>();
		ArrayList<String> novelDefs = new ArrayList<String>();
		for(int i=0;i<tokDefs.size(); i++)
		{
			if(tokNames.get(i).equals(tokDefs.get(i).get(0)))//time to remove left recursion!
			{
				int index = 0;
				
				while(tokDefs.get(i).get(index)!= "|")
				{
					index++;
				}//end while loop
				
				index++;
				newDefs.add("(");
				
				while(index<tokDefs.get(i).size())
				{
					newDefs.add(tokDefs.get(i).get(index));
				}//end while loop
				
				newDefs.add(")");
				newName = tokNames.get(i) + "tail";
				newDefs.add(newName);
				int in = 1;
				
				while(tokDefs.get(i).get(in)!="|")
				{
					novelDefs.add(tokDefs.get(i).get(in));
					in++;
				}//end while loop
				
				novelDefs.add(newName);
				novelDefs.add("|");
				novelDefs.add("");
				
				names.add(tokNames.get(i));
				names.add(newName);
				defs.add(newDefs);
				defs.add(novelDefs);
			}//end if statement
			else
			{
				names.add(tokNames.get(i));
				defs.add(tokDefs.get(i));
			}//end else statement
		}//end for loop
		fixedSpecName = names;
		fixedSpecDef = defs;
	}//end removeLeftRecursion method
	
	public BST<String> createParseTree()//check for new root!!!!!!
	{
		BST<String> parseTree = new BST<String>();
		ArrayList<BSTNode<String>> begParens = new ArrayList<BSTNode<String>>();
		ArrayList<BSTNode<String>> begClause = new ArrayList<BSTNode<String>>();
		ArrayList<BSTNode<String>> leaves = new ArrayList<BSTNode<String>>();
		BSTNode<String> curNode = new BSTNode<String>();
		ArrayList<String> seenToks = new ArrayList<String>();
		int numParens = 0;
		int numEndParens = 0;
		int curClause = 0;
		boolean curIsLeft = true;
		boolean seen = false;
		boolean beginParen = false;
		BSTNode<String> curHead = new BSTNode<String>(fixedSpecName.get(0), false);
		BSTNode<String> root = curHead;
		
		
		for(int i = 0; i<fixedSpecName.size();i++)
		{
			for(int index = 0; index<fixedSpecDef.get(i).size();index++)
			{
				String def = fixedSpecDef.get(i).get(index);
				switch(def.charAt(0))
				{
					case '|':
						if(numParens>0)
						{
							BSTNode<String> newNode = new BSTNode<String>("|", false);
							newNode.setLeftChild(begParens.get(numParens-1).getLeftChild());
							begParens.get(numParens-1).getLeftChild().setParent(newNode);
							if(seenToks.indexOf(fixedSpecDef.get(i).get(index+1))>-1)
							{
								BSTNode<String> newRight=new BSTNode<String>(fixedSpecDef.get(i).get(index+1), true);
								newNode.setRightChild(newRight);
								newRight.setParent(newNode);
								newNode.setParent(begParens.get(numParens-1));
								if(curIsLeft)
								{
									begParens.get(numParens-1).setLeftChild(newNode);
								}//end if statement
								else
								{
									begParens.get(numParens-1).setRightChild(newNode);
								}//end else statement
								seen = true;
								curNode = newRight;
								curIsLeft = false;
								leaves.add(newRight);
								begClause.add(newRight);
								curClause++;
								recursions.put(newRight, (BSTNode<String>)parseTree.find(fixedSpecDef.get(i).get(index+1)));
							}//end if statement
							else
							{
								BSTNode<String> newRight=new BSTNode<String>(fixedSpecDef.get(i).get(index+1), false);
								newNode.setRightChild(newRight);
								newRight.setParent(newNode);
								newNode.setParent(begParens.get(numParens-1));
								if(curIsLeft)
								{
									begParens.get(numParens-1).setLeftChild(newNode);
								}//end if statement
								else
								{
									begParens.get(numParens-1).setRightChild(newNode);
								}//end else statement
								seen = true;
								curNode = newRight;
								curIsLeft = false;
								leaves.add(newRight);
								begClause.add(newRight);
								curClause++;
								seenToks.add(fixedSpecDef.get(i).get(index+1));
							}//end else statement
						}//end if statement
						else
						{
							BSTNode<String> newNode0 = new BSTNode<String>("|", false);
							newNode0.setLeftChild(begClause.get(curClause).getLeftChild());
							begClause.get(curClause).getLeftChild().setParent(newNode0);
							if(seenToks.indexOf(fixedSpecDef.get(i).get(index+1))>-1)
							{
								BSTNode<String> newRight0 = new BSTNode<String>(fixedSpecDef.get(i).get(index+1), true);
								newNode0.setRightChild(newRight0);
								newRight0.setParent(newNode0);
								newNode0.setParent(begClause.get(curClause));
								if(curIsLeft)
								{
									begClause.get(curClause).setLeftChild(newNode0);
								}//end if statement
								else
								{
									begClause.get(curClause).setRightChild(newNode0);
								}//end else statement
								seen=true;
								curNode = newRight0;
								curIsLeft = false;
								leaves.add(newRight0);
								begClause.add(newRight0);
								curClause++;
								recursions.put(newRight0, (BSTNode<String>)parseTree.find(fixedSpecDef.get(i).get(index+1)));
							}//end if statement
							else
							{
								BSTNode<String> newRight0 = new BSTNode<String>(fixedSpecDef.get(i).get(index+1), false);
								newNode0.setRightChild(newRight0);
								newRight0.setParent(newNode0);
								newNode0.setParent(begClause.get(curClause));
								if(curIsLeft)
								{
									begClause.get(curClause).setLeftChild(newNode0);
								}//end if statement
								else
								{
									begClause.get(curClause).setRightChild(newNode0);
								}//end else statement
								seen=true;
								curNode = newRight0;
								curIsLeft = false;
								leaves.add(newRight0);
								begClause.add(newRight0);
								curClause++;
								seenToks.add(fixedSpecDef.get(i).get(index+1));
							}//end else statement
							
						}//end else statement
						break;
					case '*':
						if(fixedSpecDef.get(i).get(index-1).equals(")"))
						{
							BSTNode<String> newNode = new BSTNode<String>("*", false);
							newNode.setLeftChild(begParens.get(numParens));
							newNode.setParent(begParens.get(numParens).getParent());
							if(curIsLeft)
							{
								begParens.get(numParens).getParent().setLeftChild(newNode);
							}//end if statement
							else
							{
								begParens.get(numParens).getParent().setRightChild(newNode);
							}//end else statement
							begParens.get(numParens).setParent(newNode);
							seen = false;
							curIsLeft = true;
							curNode = newNode;
						}//end if statement
						else
						{
							BSTNode<String> newNode1 = new BSTNode<String>("*", false);
							newNode1.setLeftChild(curNode);
							newNode1.setParent(curNode.getParent());
							if(curIsLeft)
							{
								curNode.getParent().setLeftChild(newNode1);
							}//end if statement
							else
							{
								curNode.getParent().setRightChild(newNode1);
							}//end else statement
							curNode.setParent(newNode1);
							curIsLeft = true;
							seen = false;
							curNode = newNode1;
						}//end else statement
						break;
					case '+':
						if(fixedSpecDef.get(i).get(index-1).equals(")"))
						{
							BSTNode<String> newNode = new BSTNode<String>("+", false);
							newNode.setLeftChild(begParens.get(numParens));
							newNode.setParent(begParens.get(numParens).getParent());
							if(curIsLeft)
							{
								begParens.get(numParens).getParent().setLeftChild(newNode);
							}//end if statement
							else
							{
								begParens.get(numParens).getParent().setRightChild(newNode);
							}//end else statement
							begParens.get(numParens).setParent(newNode);
							seen = false;
							curIsLeft = true;
							curNode = newNode;
						}//end if statement
						else
						{
							BSTNode<String> newNode2 = new BSTNode<String>("+", false);
							newNode2.setLeftChild(curNode);
							newNode2.setParent(curNode.getParent());
							if(curIsLeft)
							{
								curNode.getParent().setLeftChild(newNode2);
							}//end if statement
							else
							{
								curNode.getParent().setRightChild(newNode2);
							}//end else statement
							curNode.setParent(newNode2);
							curIsLeft = true;
							seen = false;
							curNode = newNode2;
						}//end else statement
						break;
					case '('://begins new clause
						if(index==0)
						{
							numParens++;
							BSTNode<String> newNode = new BSTNode<String>("", false);
							curNode = newNode;
							begParens.add(newNode);
							seen = false;
							curHead.setLeftChild(curNode);
							curNode.setParent(curHead);
							begClause.add(newNode);
							curClause++;
							curIsLeft = true;
							leaves.add(newNode);
						}//end if statement
						else
						{
							numParens++;
							BSTNode<String> newNode = new BSTNode<String>("", false);
							begParens.add(newNode);
							seen = false;
							curNode.setLeftChild(newNode);
							newNode.setParent(curNode);
							begClause.add(newNode);
							curClause++;
							curIsLeft = true;
							curNode = newNode;
						}//end else statement
						break;
					case ')'://begins new clause
						curClause++;
						numEndParens++;
						BSTNode<String> newNode4 = new BSTNode<String>("", false);
						curNode.setLeftChild(newNode4);
						newNode4.setParent(curNode);
						curNode = newNode4;
						begClause.add(newNode4);
						curIsLeft = true;
						seen = false;
						break;
					default://concatenation
						if(index==0)
						{
							if(i==0)
							{
								BSTNode<String> newNode = new BSTNode<String>(fixedSpecDef.get(i).get(index), false);
								curNode = newNode;
								seenToks.add(fixedSpecDef.get(i).get(index));
								seen = false;
								curHead.setLeftChild(curNode);
								curNode.setParent(curHead);
								begClause.add(newNode);
								curClause++;
								curIsLeft = true;
								leaves.add(newNode);
							}//end if statement
							else
							{
								if(seenToks.indexOf(fixedSpecDef.get(i).get(index))>-1)
								{
									BSTNode<String> newNode = new BSTNode<String>(fixedSpecDef.get(i).get(index), true);
									curNode = newNode;
									seenToks.add(fixedSpecDef.get(i).get(index));
									seen = false;
									curHead.setLeftChild(curNode);
									curNode.setParent(curHead);
									begClause.add(newNode);
									curClause++;
									curIsLeft = true;
									leaves.add(newNode);
									recursions.put(newNode, (BSTNode<String>)parseTree.find(fixedSpecDef.get(i).get(index)));
								}//end if statement
								else
								{
									BSTNode<String> newNode = new BSTNode<String>(fixedSpecDef.get(i).get(index), false);
									curNode = newNode;
									seenToks.add(fixedSpecDef.get(i).get(index));
									seen = false;
									curHead.setLeftChild(curNode);
									curNode.setParent(curHead);
									begClause.add(newNode);
									curClause++;
									seenToks.add(fixedSpecDef.get(i).get(index));
									curIsLeft = true;
									leaves.add(newNode);
								}
							}//end else statement
						}//end if statement
						else if(fixedSpecDef.get(i).get(index-1).equals(")"))
						{
							BSTNode<String> newNode = new BSTNode<String>("con", false);
							newNode.setLeftChild(begParens.get(numParens));
							if(seenToks.indexOf(fixedSpecDef.get(i).get(index))>-1)
							{
								BSTNode<String> newRight=new BSTNode<String>(fixedSpecDef.get(i).get(index), true);
								newNode.setRightChild(newRight);
								newRight.setParent(newNode);
								newNode.setParent(begParens.get(numParens).getParent());
								if(curIsLeft)
								{
									begParens.get(numParens).getParent().setLeftChild(newNode);
								}//end if statement
								else
								{
									begParens.get(numParens).getParent().setRightChild(newNode);
								}//end else statement
								begParens.get(numParens).setParent(newNode);
								seen = true;
								curIsLeft = false;
								curNode = newRight;
								leaves.add(newRight);
								begClause.add(curNode);
								curClause++;
								recursions.put(newRight, (BSTNode<String>)parseTree.find(fixedSpecDef.get(i).get(index)));
							}//end if statement
							else
							{
								seenToks.add(fixedSpecDef.get(i).get(index));
								BSTNode<String> newRight=new BSTNode<String>(fixedSpecDef.get(i).get(index), false);
								newNode.setRightChild(newRight);
								newRight.setParent(newNode);
								newNode.setParent(begParens.get(numParens).getParent());
								if(curIsLeft)
								{
									begParens.get(numParens).getParent().setLeftChild(newNode);
								}//end if statement
								else
								{
									begParens.get(numParens).getParent().setRightChild(newNode);
								}//end else statement
								begParens.get(numParens).setParent(newNode);
								seen = true;
								curIsLeft = false;
								curNode = newRight;
								leaves.add(newRight);
								begClause.add(curNode);
								curClause++;
							}//end else statement
						}//end if statement
						else if(fixedSpecDef.get(i).get(index-1).equals("|"))
						{
							seen=false;
						}//end else if statement
						else if(fixedSpecDef.get(i).get(index-1).equals("("))
						{
							if(index<2)
							{
								if(seenToks.indexOf(fixedSpecDef.get(i).get(index))>-1)
								{
									BSTNode<String> newNode = new BSTNode<String>(fixedSpecDef.get(i).get(index), true);
									curNode = newNode;
									recursions.put(newNode, (BSTNode<String>)parseTree.find(fixedSpecDef.get(i).get(index)));
								}//end if statement
								else
								{
									BSTNode<String> newNode = new BSTNode<String>(fixedSpecDef.get(i).get(index), true);
									curNode = newNode;
									seenToks.add(fixedSpecDef.get(i).get(index));
								}//end else statement
							}//end if statement
							else
							{
								BSTNode<String> newNode3 = new BSTNode<String>("con", false);
								newNode3.setLeftChild(curNode.getParent());
								if(seenToks.indexOf(fixedSpecDef.get(i).get(index))>-1)
								{
									BSTNode<String> newRight3 = new BSTNode<String>(fixedSpecDef.get(i).get(index), true);
									newNode3.setRightChild(newRight3);
									newRight3.setParent(newNode3);
									newNode3.setParent(curNode.getParent().getParent());
									if(curIsLeft)
									{
										curNode.getParent().getParent().setLeftChild(newNode3);
									}//end if statement
									else
									{
										curNode.getParent().getParent().setRightChild(newNode3);
									}//end else statement
									curNode.getParent().setParent(newNode3);
									curIsLeft = false;
									seen = false;
									curNode = newRight3;
									leaves.add(curNode);
									recursions.put(newRight3, (BSTNode<String>)parseTree.find(fixedSpecDef.get(i).get(index)));
								}//end if statement
								else
								{
									seenToks.add(fixedSpecDef.get(i).get(index));
									BSTNode<String> newRight3 = new BSTNode<String>(fixedSpecDef.get(i).get(index), false);
									newNode3.setRightChild(newRight3);
									newRight3.setParent(newNode3);
									newNode3.setParent(curNode.getParent().getParent());
									if(curIsLeft)
									{
										curNode.getParent().getParent().setLeftChild(newNode3);
									}//end if statement
									else
									{
										curNode.getParent().getParent().setRightChild(newNode3);
									}//end else statement
									curNode.getParent().setParent(newNode3);
									curIsLeft = false;
									seen = false;
									curNode = newRight3;
									leaves.add(curNode);
								}//end else statement
							}//end else
						}//end else if statement
						else
						{
							BSTNode<String> newNode3 = new BSTNode<String>("con", false);
							newNode3.setLeftChild(curNode);
							if(seenToks.indexOf(fixedSpecDef.get(i).get(index))>-1)
							{
								BSTNode<String> newRight3 = new BSTNode<String>(fixedSpecDef.get(i).get(index), true);
								newNode3.setRightChild(newRight3);
								newRight3.setParent(newNode3);
								newNode3.setParent(curNode.getParent());
								if(curIsLeft)
								{
									curNode.getParent().setLeftChild(newNode3);
								}//end if statement
								else
								{
									curNode.getParent().setRightChild(newNode3);
								}//end else statement
								curNode.setParent(newNode3);
								curIsLeft = false;
								seen = false;
								curNode = newRight3;
								leaves.add(curNode);
								recursions.put(newRight3, (BSTNode<String>)parseTree.find(fixedSpecDef.get(i).get(index)));
							}//end if statement
							else
							{
								seenToks.add(fixedSpecDef.get(i).get(index));
								BSTNode<String> newRight3 = new BSTNode<String>(fixedSpecDef.get(i).get(index), false);
								newNode3.setRightChild(newRight3);
								newRight3.setParent(newNode3);
								newNode3.setParent(curNode.getParent());
								if(curIsLeft)
								{
									curNode.getParent().setLeftChild(newNode3);
								}//end if statement
								else
								{
									curNode.getParent().setRightChild(newNode3);
								}//end else statement
								curNode.setParent(newNode3);
								curIsLeft = false;
								seen = false;
								curNode = newRight3;
								leaves.add(curNode);
							}//end else statement
						}//end else statement
						break;
				}//end switch statement
			}//end for loop
			
		}//end for loop
		return parseTree;
	}//end createParseTree method
	
	public NFA<String> createNFA(BST<String> parseTree)
	{
		NFA<String> nfa = new NFA<String>();
		return nfa;
	}//end createNFA method
	
	public void createDFATable()//return type to be changed to data structure we decide on for DFATable
	{
		
	}//end createDFATable method
}//end DFAParserGenerator class


